`timescale	1ps/1ps
module a3_mcu_top(
		//时钟和复位
		input	wire			resetb,
		input   wire			sclk,
                
		//jtag接口
		input	wire			JTRST,
		input	wire			JTCK,
		input	wire			JTDI,
		input	wire			JTMS,
		output	wire			JTDO,

		//FPGA模块Flash控制
		input	wire			fpga_f_CS_n,
		input	wire			fpga_f_SCK,
		input	wire			fpga_f_SI,
		output	wire			fpga_f_SO,

		//flash接口
		output	reg				flash_CS_n,
		output	reg				flash_SCK,
		output	reg				flash_SI,
		input	wire			flash_SO,

		//内部配置总线
		output	wire			w_d_ok,
		output	wire	[27:0]	w_addr,
		output	wire	[31:0]	w_data,
		output	wire			r_flag,
		output	wire	[27:0]	r_addr,
		input	wire	[31:0]	r_data,
		
		//GPIO
		inout	tri		[7:0]	mcu_io_a,
		input	wire	[7:0]	mcu_in_b,
		output	wire	[7:0]	mcu_out_c,
		
		//GPIO
		output	wire			UART_TXD,
		input	wire			UART_RXD,

		//调试信号
		output	wire	[31:0]	tout
		);

//**********************************************/
//        	信号定义
/***********************************************/
reg		[3:0]	clk_div;
wire			mcu_clk;

wire	[1:0]	hresp, htrans;
wire	[2:0]	hsize;
wire			hwrite, hsel, hready;
wire	[31:0]	haddr, hwdata, hrdata;

wire			mcu_f_CS_n, mcu_f_SCK, mcu_f_SI, mcu_f_SO;

wire	[7:0]	GPIO0_I, GPIO0_O, nGPEN0;
wire	[7:0]	GPIO1_I, GPIO1_O, nGPEN1;
wire	[7:0]	GPIO2_I, GPIO2_O, nGPEN2;

wire	[31:0]	core_tout;

wire			mcu_init;
reg				mcu_flash_en;

//**********************************************/
//        	mcu时钟
/***********************************************/
always @(posedge sclk)
	clk_div <= clk_div + 1;
	
assign	mcu_clk = clk_div[3];

//**********************************************/
//        	mcu相关模块
/***********************************************/
//MCU内核
mcu_agm_core    mcu_core(
		//时钟和复位
    	.resetb					(resetb),
		.mcu_clk				(mcu_clk),
 
 		//初始化标志
		.init_flag				(mcu_init),
		
		//JTAG调试
    	.JTRST                  (JTRST),
    	.JTCK                   (JTCK),
    	.JTDI                   (JTDI),
    	.JTMS					(JTMS),
    	.JTDO                   (JTDO),
 
		//Flash接口
    	.FLASH_BIAS             (24'hB0000),
    	.FLASH_CS_n             (mcu_f_CS_n),
		.FLASH_SCK              (mcu_f_SCK),
    	.FLASH_SI				(mcu_f_SI),
    	.FLASH_SO				(mcu_f_SO),

		//共享RAM接口
    	.EXT_RAM_EN             (EXT_RAM_EN),
    	.EXT_RAM_WR             (EXT_RAM_WR),
    	.EXT_RAM_ADDR           (EXT_RAM_ADDR),
    	.EXT_RAM_BYTE_EN        (EXT_RAM_BYTE_EN),
    	.EXT_RAM_WDATA          (EXT_RAM_WDATA),
    	.EXT_RAM_RDATA          (EXT_RAM_RDATA),
 
		//AHB接口
		.htrans					(htrans),
    	.hsize					(hsize),
		.hsel					(hsel),
		.hwrite					(hwrite),
    	.haddr					(haddr),
		.hwdata					(hwdata),
    	.hrdata					(hrdata),
		.hresp					(hresp),
    	.hready					(hready),

  		//串口
		.UART_RXD               (UART_RXD),
    	.UART_TXD               (UART_TXD),

  		//GPIO
    	.GPIO0_I                (GPIO0_I),
    	.GPIO0_O                (GPIO0_O),
    	.nGPEN0                 (nGPEN0),
    	.GPIO1_I                (GPIO1_I),
    	.GPIO1_O                (GPIO1_O),
    	.nGPEN1                 (nGPEN1),
    	.GPIO2_I                (GPIO2_I),
    	.GPIO2_O                (GPIO2_O),
    	.nGPEN2                 (nGPEN2),
    		
    	.tout               	(core_tout)
		);

//**************************************************************
//        		Flash选通
//**************************************************************
always @( * )
	mcu_flash_en <= 0;

always @( * )
	if ((mcu_init == 1) || (mcu_flash_en == 1)) begin
		flash_CS_n	<= mcu_f_CS_n;
		flash_SCK	<= mcu_f_SCK;
		flash_SI	<= mcu_f_SI;
		end
	else begin
		flash_CS_n	<= fpga_f_CS_n;
		flash_SCK	<= fpga_f_SCK;
		flash_SI	<= fpga_f_SI;
		end
		
assign	mcu_f_SO = flash_SO;
assign	fpga_f_SO = flash_SO;

//**************************************************************
//        		AHB总线
//**************************************************************
mcu_ahb_bud u_ahb_bud(
		//时钟,复位
    	.resetb		(resetb),
		.mcu_clk	(mcu_clk),
		.sclk		(sclk),
		
 		//初始化标志
		.mcu_init	(mcu_init),

		//ext ahb
    	.htrans		(htrans),
    	.hsize		(hsize),
		.hsel		(hsel),
		.hwrite		(hwrite),
    	.haddr		(haddr),
		.hwdata		(hwdata),
    	.hrdata		(hrdata),
   		.hresp		(hresp),
    	.hready		(hready),

		//内部总线
		.w_d_ok		(w_d_ok),
    	.w_addr		(w_addr),
		.w_data		(w_data),
    	.r_flag		(r_flag),
   		.r_addr		(r_addr),
    	.r_data		(r_data),
						
		//调试信号
    	.tout		()
		);

//**************************************************************
//        		GPIO
//**************************************************************
assign	mcu_io_a[0] = (nGPEN0[0] == 0)? 	GPIO0_O[0]	:1'bz;
assign	mcu_io_a[1] = (nGPEN0[1] == 0)? 	GPIO0_O[1]	:1'bz;
assign	mcu_io_a[2] = (nGPEN0[2] == 0)? 	GPIO0_O[2]	:1'bz;
assign	mcu_io_a[3] = (nGPEN0[3] == 0)? 	GPIO0_O[3]	:1'bz;
assign	mcu_io_a[4] = (nGPEN0[4] == 0)? 	GPIO0_O[4]	:1'bz;
assign	mcu_io_a[5] = (nGPEN0[5] == 0)? 	GPIO0_O[5]	:1'bz;
assign	mcu_io_a[6] = (nGPEN0[6] == 0)? 	GPIO0_O[6]	:1'bz;
assign	mcu_io_a[7] = (nGPEN0[7] == 0)? 	GPIO0_O[7]	:1'bz;

//Port A, 双向IO
assign	GPIO0_I = mcu_io_a;
//Port B, 输入用
assign	GPIO1_I = mcu_in_b;
//Port C, 输出用
assign	mcu_out_c = {GPIO0_O[2:0], nGPEN0[0], GPIO2_O[3:0]};

//**************************************************************
//        		AHB总线转换
//**************************************************************

//**************************************************************
//        		调试信号
//**************************************************************
//assign tout = mcu_io_a;
//assign	tout[15:0] = { hrdata[1:0], mcu_clk, haddr[30], haddr[2], haddr[0], hwdata[1:0], hready, hsel, hwrite, hsize, htrans};
assign	tout[15:0] = { hrdata[1:0], mcu_clk, haddr[30], haddr[2], haddr[0], hwdata[1:0], hready, hsel, hwrite, hsize, htrans};
assign	tout[19:16] = {r_flag, w_addr[0], w_data[0], w_d_ok};
assign	tout[31:20] = 20'h00000;

endmodule
